#include "ufilechooseredit.h"
#include "ufilechooseredit_p.h"
#include "ulineedit.h"

#include <QScreen>
#include <QGuiApplication>
#include <QWindow>
#include <QPushButton>
#include <QStyle>
#include <QHBoxLayout>

void UFileChooserEditPrivate::init()
{
    Q_Q(UFileChooserEdit);

    lineEdit = new ULineEdit(q);
    lineEdit->setReadOnly(true);
    button = new ULineEditButton(q);
    button->setBackGroundColor(q->palette().color(QPalette::Highlight));
    button->setFlat(true);

    QHBoxLayout* layout = new QHBoxLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(lineEdit);
    layout->addSpacing(5);
    layout->addWidget(button);
    q->setLayout(layout);

    button->setAccessibleName("FileChooserEditButton");
    button->setIcon(q->style()->standardIcon(QStyle::SP_DialogOpenButton, nullptr));
    button->setIconSize(QSize(20, 20));

    q->setDialogDisplayPosition(UFileChooserEdit::DialogDisplayPosition::CurrentMonitorCenter);

    QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_showFileChooserDialog()));
}

void UFileChooserEditPrivate::_q_showFileChooserDialog()
{
    Q_Q(UFileChooserEdit);

    if (!dialog)
    {
        q->initDialog();
    }
    if (dialog == nullptr)
    {
        return;
    }
    if (dialogDisplayPosition == UFileChooserEdit::CurrentMonitorCenter)
    {
        QPoint pos = QCursor::pos();

        for (const QScreen* screen : qApp->screens())
        {
            if (screen->geometry().contains(pos))
            {
                QRect rect = dialog->geometry();
                rect.moveCenter(screen->geometry().center());
                dialog->move(rect.topLeft());
                break;
            }
        }
    }

    q->dialogOpened();

    if (!dialog)
    {
        qWarning("init filedialog failed!!");
        return;
    }

    if (dialog->isVisible())
        dialog->setVisible(false);

    int code = dialog->exec();

    if (code == QDialog::Accepted && !dialog->selectedFiles().isEmpty())
    {
        const QString fileName = dialog->selectedFiles().first();

        lineEdit->setText(fileName);
        Q_EMIT q->fileChoosed(fileName);
    }

    if (qApp->modalWindow() == dialog->windowHandle())
        dialog->close();

    q->dialogClosed(code);
}

UFileChooserEdit::UFileChooserEdit(QWidget* parent)
    : QWidget(parent), d_ptr(new UFileChooserEditPrivate(this))
{
    Q_D(UFileChooserEdit);

    d->init();
}

UFileChooserEdit::~UFileChooserEdit()
{
}

UFileChooserEdit::DialogDisplayPosition UFileChooserEdit::dialogDisplayPosition() const
{
    Q_D(const UFileChooserEdit);

    return d->dialogDisplayPosition;
}

void UFileChooserEdit::setDialogDisplayPosition(UFileChooserEdit::DialogDisplayPosition dialogDisplayPosition)
{
    Q_D(UFileChooserEdit);

    d->dialogDisplayPosition = dialogDisplayPosition;
}

void UFileChooserEdit::setFileDialog(QFileDialog* fileDialog)
{
    Q_D(UFileChooserEdit);

    d->dialog = fileDialog;
}

QFileDialog* UFileChooserEdit::fileDialog() const
{
    Q_D(const UFileChooserEdit);

    return d->dialog;
}

ULineEdit* UFileChooserEdit::lineEidt() const
{
    Q_D(const UFileChooserEdit);

    return d->lineEdit;
}

void UFileChooserEdit::initDialog()
{
    Q_D(UFileChooserEdit);

    if (d->dialog)
    {
        return;
    }

    d->dialog = new QFileDialog(this);
    d->dialog->setAcceptMode(QFileDialog::AcceptOpen);
    d->dialog->setFileMode(QFileDialog::ExistingFile);
}

QString UFileChooserEdit::fileName() const
{
    Q_D(const UFileChooserEdit);

    return d->lineEdit->text().trimmed();
}

void UFileChooserEdit::clear()
{
    Q_D(UFileChooserEdit);

    d->lineEdit->clear();
}

void UFileChooserEdit::setFileMode(QFileDialog::FileMode mode)
{
    Q_D(UFileChooserEdit);

    if (!d->dialog)
    {
        initDialog();
    }
    d->dialog->setFileMode(mode);
}

QFileDialog::FileMode UFileChooserEdit::fileMode() const
{
    Q_D(const UFileChooserEdit);

    if (!d->dialog)
    {
        return QFileDialog::FileMode::AnyFile;
    }
    return d->dialog->fileMode();
}

void UFileChooserEdit::setNameFilters(const QStringList &filters)
{
    Q_D(UFileChooserEdit);

    if (!d->dialog)
    {
        initDialog();
    }
    d->dialog->setNameFilters(filters);
}

QStringList UFileChooserEdit::nameFilters() const
{
    Q_D(const UFileChooserEdit);

    if (!d->dialog)
    {
        return QStringList();
    }
    return d->dialog->nameFilters();
}

void UFileChooserEdit::setDirectoryUrl(const QUrl &directory)
{
    Q_D(UFileChooserEdit);

    if (!d->dialog)
    {
        initDialog();
    }
    d->dialog->setDirectoryUrl(directory);
}

QUrl UFileChooserEdit::directoryUrl()
{
    Q_D(UFileChooserEdit);

    if (!d->dialog)
    {
        initDialog();
    }
    return d->dialog->directoryUrl();
}

void UFileChooserEdit::resizeEvent(QResizeEvent* event)
{
    Q_D(UFileChooserEdit);

    d->button->setFixedSize(QSize(d->lineEdit->height(), d->lineEdit->height()));
    QWidget::resizeEvent(event);
}

#include "moc_ufilechooseredit.cpp"
